/**************************************************
 * File  : embSnakeDevice.c
 * Author: MANDA (slipperstree@gmail.com)
 * Date  : 2019.11
 * Updt  : 2021.07
 * Func  : 设备驱动模块，请自行实现本文件内的各函数以适配你的设备，外部会在需要的时候调用这些函数
***************************************************/

#include "embSnakeDevice.h"

#include "boradSupport.h"
#include "st7789.h"

// =========================================================================================
// ==    显示设备相关    =====================================================================
// =========================================================================================

// 初始化显示设备
// bgColor : 背景色，可用于初期清屏
void devDisplayInit(u16 bgColor){
    LCD_Init();
    devScreenOFF(); // 关闭LCD显示
    LCD_Clear(bgColor);
    devScreenON();  // 打开LCD显示
    TFT_BL = 0;     // 打开液晶屏背光灯
}

// 填充一个矩形区域
void devFillRectange(u16 x, u16 y, u16 width, u16 height, u16 color){
    LCD_Fill(x, y, x+width-1, y+height-1, color);
}

// 为绘制一个区域做准备。（外部调用了这个函数后会批量调用devPointInDrawArea来绘制各种图案或点阵文字）
// 一般来说在这里调用底层的设置显示区域命令以及开始绘图命令
// LCD_SetArea(startX, startY, startX+areaWidth-1, startY+areaHeight-1);
// LCD_WR_REG(0x2C);
void devPrepareForDrawArea(unsigned int startX, unsigned int startY, unsigned int areaWidth, unsigned int areaHeight){
    LCD_SetArea(startX, startY, startX+areaWidth-1, startY+areaHeight-1);
	LCD_WR_REG(0x2C);
}

// 绘制一个指定颜色的点，无需考虑坐标位置。（外部会先调用函数devPrepareForDrawArea以确定绘图范围）
void devPointInDrawArea(unsigned int color){
    LcdWirteColorData(color);
}

// 绘制直线
void devDrawLine(unsigned int x1, unsigned int y1, unsigned int x2, unsigned int y2, unsigned int width, unsigned int color){
    LCD_DrawLine_Color(x1, y1, x2, y2, width, color);
}

// 关闭屏幕显示(跟函数devScreenON搭配使用，如无必要可不用实现留空即可，实现了更好，可以防止刷新画面的过程被用户看见)
void devScreenOFF(){
    LCD_WR_REG(0x28);
}

// 打开屏幕显示(跟函数devScreenOFF搭配使用，如无必要可不用实现留空即可，实现了更好，可以防止刷新画面的过程被用户看见)
void devScreenON(){
    LCD_WR_REG(0x29);
}

// =========================================================================================
// ==    按键相关       =====================================================================
// =========================================================================================
// TODO:

// =========================================================================================
// ==    储存相关       =====================================================================
// =========================================================================================
// TODO:

// =========================================================================================
// ==    声音相关       =====================================================================
// =========================================================================================

// 播放声音
void devPlaySound(Sound_Type soundType){

    switch (soundType)
    {
    case SOUND_EAT_APPLE:
        BEEP_SHORT();
        break;
    case SOUND_HISCORE:
        break;
    case SOUND_MENU:
        break;
    case SOUND_DEAD:
        break;
    case SOUND_GAMEOVER:
        break;
    default:
        break;
    }
}

// =========================================================================================
// ==    画面相关       =====================================================================
// =========================================================================================

// 进入主画面时会调用这个函数，如有需要请实现想要的效果(比如关闭LED)
// 没有要做的留空即可
void devEnterHomePage(){
    LED_ALL_OFF();
}

// 进入Demo画面时会调用这个函数，如有需要请实现想要的效果
// 没有要做的留空即可
void devEnterDemoPage(){
    
}

// 进入游戏画面时会调用这个函数，如有需要请实现想要的效果
// 没有要做的留空即可
void devEnterGamePage(){
    
}

// 进入GameOver画面时会调用这个函数，如有需要请实现想要的效果
// 没有要做的留空即可
void devEnterGameOverPage(){
    
}

// =========================================================================================
// ==    其他          =====================================================================
// =========================================================================================
                                
// 当玩家改变游戏速度时会调用这个函数，请实现想要的效果(比如点亮不同的LED)
void devSpeedChanged(unsigned int speed){

    switch (speed)
    {
    case SPEED_DEMO_L:
        LED_ALL_OFF();
        break;
    case SPEED_DEMO_M:
        LED_R_ON();
        LED_Y_OFF();
        LED_G_OFF();
        break;
    case SPEED_DEMO_H:
        LED_R_ON();
        LED_Y_ON();
        LED_G_OFF();
        break;
    case SPEED_DEMO_S:
        LED_ALL_ON();
        break;
    default:
        break;
    }
}

